<?php
/*
$_FILES['myFile']['name']   客户端文件的原名称。
$_FILES['myFile']['type']   文件的 MIME 类型，需要浏览器提供该信息的支持，例如"image/gif"。
$_FILES['myFile']['size']   已上传文件的大小，单位为字节。
$_FILES['myFile']['tmp_name']   文件被上传后在服务端储存的临时文件名，一般是系统默认。可以在php.ini的upload_tmp_dir 指定，但 用 putenv() 函数设置是不起作用的。
$_FILES['myFile']['error']   和该文件上传相关的错误代码。['error'] 是在 PHP 4.2.0 版本中增加的。下面是它的说明：(它们在PHP3.0以后成了常量)
UPLOAD_ERR_OK
值：0; 没有错误发生，文件上传成功。
UPLOAD_ERR_INI_SIZE
值：1; 上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
UPLOAD_ERR_FORM_SIZE
值：2; 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
UPLOAD_ERR_PARTIAL
值：3; 文件只有部分被上传。
UPLOAD_ERR_NO_FILE
值：4; 没有文件被上传。
值：5; 上传文件大小为0


10：不允许此类文件上传
11：大小超过此类文件的限制范围
12：保存文件的目录不存在
16：文件保存失败
要求：
不同的用户存放在不同的目录，按月自动保存目录，同一个用户的文件放在一起

* 使用方法：

*/
class Upload_Lib {
	protected $config;
	protected $isRealName;
	protected $saveDir;
	protected $time;
	protected $rand;
	
	//上传成功后，返回此信息
	public $uploads = array();
	
	public function __construct(){
		global $_CONFIG;
		
		$this->config = array(
			'allowType'=>array(
				'image'=>array('jpg', 'gif', 'png', 'swf'),
				'file'=>array('txt', 'doc', 'xls', 'pdf', 'rar', 'js'),
				'js'=>array('js'),
				'css'=>array('css')
			),
			'saveDir'=>array(
				'image'=>'./upload/images/',
				'file'=>'./upload/files/',
				'js'=>'./upload/js/',
				'css'=>'./upload/css/'
			),
			'maxSize'=>array(
				'image'=>1024 * 1024,
				'file'=>1024 * 1024 * 3,
				'js'=>1024 * 10,
				'css'=>1024 * 10
			)
		);
		
		if (isset($_CONFIG['upload'])){
			$config = $_CONFIG['upload'];
			foreach($config as $key => $value){
				$this->config[$key] = $value;
			}
		}
	}
	
	/**
	 * 返回文件不带"."的扩展名，如 rar
	 *
	 * @return string
	 */
	protected function getExtension($fileName) {
		return pathinfo($fileName, PATHINFO_EXTENSION);
	}
	
	/**
	关键扩展名获取类型
	*/
	protected function getType($ext){
		$allow = $this->config['allowType'];
		
		foreach($allow as $key => $arr){
			if (in_array($ext, $arr)){
				return $key;
			}
		}
		
		return false;
	}
	
	/**
	 创建多级目录，只能在网站根目录之内创建，以确保安全
	*/
	protected function makeDir($path){
	    if(!$path) return 0;
		$path  = str_replace("\\", '/', $path);
		
		if (!file_exists($path)){
			$this->makeDir(dirname($path));
			mkdir($path, 0777);
	    }
	}
	
	/**
	验证文件的类型、大小
	*/
	protected function check(& $FILE){
		$c = $FILE;
		$uptype = $c['uptype'];
		if (! $uptype) {
			$this->uploads['failure'][] = array('name'=>$c['name'], 'error'=>10);
			return false;
		}
		
		if ($c['size'] > $this->config['maxSize'][$uptype]){
			$this->uploads['failure'][] = array('name'=>$c['name'], 'error'=>11);
			return false;
		}
		$path = $c['save_dir'];
		$this->makeDir($path);
		if (!is_dir($path)){
			$this->uploads['failure'][] = array('name'=>$c['name'], 'error'=>12, 'path'=>$path);
			return false;
		}
		
		return true;
	}
	
	protected function newName(){
		
		return date('His', $this->time).$this->rand;
	}
	
	protected function move(& $FILE, $index = null){
		$c = array('save_dir'=>'../photos/');
		$this->time = time();
		$this->rand = rand(1000,9999);
		
		if (is_null($index)){
			$c['name']=$FILE['name'];
			$c['type']=$FILE['type'];
			$c['tmp_name']=$FILE['tmp_name'];
			$c['error']=$FILE['error'];
			$c['size']=$FILE['size'];
		} else {
			$c['name']=$FILE['name'][$index];
			$c['type']=$FILE['type'][$index];
			$c['tmp_name']=$FILE['tmp_name'][$index];
			$c['error']=$FILE['error'][$index];
			$c['size']=$FILE['size'][$index];
		}
		
		$c['save_name']=$this->newName();
		$c['ext'] = $this->getExtension($c['name']);
		$c['uptype'] = $this->getType($c['ext']);
		
		if ($this->config['saveDir']){//指定保存目录
			$c['save_dir'] = $this->config['saveDir'][$c['uptype']];
		}
		
		if ($this->isRealName){//是否使用真实名保存
			$c['save_name'] = $c['name'];
		}

		if ($c['tmp_name']){
			//文件上传成功，但是可能不符合规则，再进行验证
			if (!$this->check($c)) return;
			$name = $c['save_dir'].$c['save_name'].'.'.$c['ext'];
			if (move_uploaded_file($c['tmp_name'], $name)){
				$this->uploads['success'][] = array($name,$this->time,$this->rand);
			} else {
				$this->uploads['failure'][] = array('name'=>$c['name'], 'error'=>16);
			}
		} else {
			//文件没有上传成功，判断失败原因
			$this->uploads['failure'][] = array('name'=>$c['name'], 'error'=>$c['error']);
		}
	}
	
	public function save($inputname, $saveDir = '', $isRealName = false){
		if (!isset($_FILES[$inputname])) return false;
		$this->saveDir = $saveDir;
		$this->isRealName = $isRealName;
		
		$FILE = $_FILES[$inputname];
		$this->uploads = array('success'=>array(), 'failure'=>array());
		
		if (is_array($FILE['name'])){
			foreach($FILE['name'] as $index => $name){
				$this->move($FILE, $index);
			}
		} else{
			$this->move($FILE);
		}
		
		return $this->uploads;
	}
	
	protected function saves(){
		
	}

	
	public function test(){
		
	}
	
	public function show(){
		print_r($_FILES);
	}
}